import bcrypt
import os
import uuid
from fastapi import UploadFile, HTTPException
from .settings import settings


def encrypt_password(password: str) -> str:
    """
    使用 bcrypt 算法对密码进行加密
    Args:
        password: 原始密码
    Returns:
        加密后的密码哈希值字符串
    """
    hashed = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
    return hashed.decode("utf-8")


def verify_password(password: str, hashed: str) -> bool:
    """
    验证密码是否正确
    Args:
        password: 待验证的密码
        hashed: 已存储的密码哈希值字符串
    Returns:
        密码是否正确
    """
    return bcrypt.checkpw(password.encode("utf-8"), hashed.encode("utf-8"))


async def save_upload_file(file: UploadFile) -> str:
    """
    保存上传的文件
    Args:
        file: 上传的文件对象
    Returns:
        文件的访问URL
    Raises:
        HTTPException: 当文件类型不允许或文件大小超限时抛出异常
    """
    if not file:
        return ""

    # 验证文件类型
    if file.content_type not in settings.ALLOWED_IMAGE_TYPES:
        raise HTTPException(status_code=400, detail="不支持的文件类型")

    # 验证文件大小
    file_size = 0
    file_content = await file.read()
    file_size = len(file_content)
    if file_size > settings.MAX_IMAGE_SIZE:
        raise HTTPException(status_code=400, detail="文件大小超过限制")

    # 确保上传目录存在
    os.makedirs(settings.UPLOAD_DIR, exist_ok=True)

    # 生成唯一文件名
    file_ext = os.path.splitext(file.filename)[1] if file.filename else ".jpg"
    unique_filename = f"{uuid.uuid4()}{file_ext}"
    file_path = os.path.join(settings.UPLOAD_DIR, unique_filename)

    # 保存文件
    with open(file_path, "wb") as f:
        f.write(file_content)

    # 返回文件URL
    return f"/static/{unique_filename}"
